package cn.com.yang.thread;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.stream.IntStream;
import java.util.stream.LongStream;

/**
 * ForkJoinPool线程池
 * TODO
 * @author yangyijin
 * @since 2023年10月12日-上午10:02:53
 */
public class TestForkJoinPool {
	private static ForkJoinPool forkJoinPool;
	
	/**
	 * 求和任务继承 RecursiveTask
	 * ForkJoinPool 一共有三个实现：
	 * 	RecursiveTask 有返回值；
	 *  RecursiveAction 无返回值；
	 *  CountedCompleter: 无返回值任务，完成任务后可以触发回调；
	 */
	private static class SumTask extends RecursiveTask<Long>{
		
		private static final long serialVersionUID = 1L;
		private long[] numbers;
		private int from;
		private int to;
		
		public SumTask(long[] numbers,int from ,int to) {
			this.numbers = numbers;
			this.from = from;
			this.to = to;
		}
		// 核心方法
		@Override
		protected Long compute() {
			if(to-from<10) {
				long total = 0;
				for(int i=from;i<=to;i++) {
					total+=numbers[i];
				}
				return total;
			}else {
				int middl = (from+to)/2;
				SumTask taskLeft = new SumTask(numbers,from,middl);
				SumTask taskRight = new SumTask(numbers,middl+1,to);
				taskLeft.fork();//往队列里放任务
				taskRight.fork();//往队列里放任务
				return taskLeft.join()+taskRight.join();
			}
		}
	}
	
	public static void main(String[] args) {
		forkJoinPool = new ForkJoinPool();
		long[] numbers = LongStream.range(1,100000000).toArray();
		//这里可以调用submit方法返回future,通过future.get()返回结果
		Long result = forkJoinPool.invoke(new SumTask(numbers,0,numbers.length-1));
		forkJoinPool.shutdown();
		System.out.println("最终结果："+result);
        System.out.println("活跃线程数："+forkJoinPool.getActiveThreadCount());
        System.out.println("窃取任务数："+forkJoinPool.getStealCount());
	}
}
